#include <stdio.h>
#include <stdarg.h>
#include <stdbool.h>

enum Sex
{
    male = 0,
    female
};

enum Education
{
    high = 0,
    junior,
    college,
    master,
    doctor
};

struct Date
{
    int year;
    int month;
    int day;
};

struct Info
{
    int num;
    char name[20];
    enum Sex sex;
    struct Date birthday;
    enum Education education;
    char duty[20];
    int wage;
    char addr[60];
    char phone[20];
};

typedef union
{
    enum Education edu;
    int wage;
} Condition;

void recordInfo();
void viewInfo();
void queryInfo();
void editInfo();
void delInfo();

static void showInfo(struct Info*);
static void myScanf(const char*, ...);
static bool confirm(const char*);

int main()
{
    int choose = 0;

    do {
        printf("======职工信息管理系统======\n");

        printf("1.信息输入\n"
               "2.信息浏览\n"
               "3.信息查询\n"
               "4.信息修改\n"
               "5.信息删除\n"
               "0.退出\n");

        printf("\n请输入操作编号：\n");
        myScanf("%d", &choose);

        if(choose == 1)
        {
            recordInfo();
        }
        else if(choose == 2)
        {
            viewInfo();
        }
        else if(choose == 3)
        {
            queryInfo();
        }
        else if(choose == 4)
        {
            editInfo();
        }
        else if(choose == 5)
        {
            delInfo();
        }
        else if(choose == 0)
        {
            break;
        }

    } while(1);

    return 0;
}

static void myScanf(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    vscanf(fmt, ap);
    va_end(ap);
    getchar();
    return;
}

static bool confirm(const char *prompt)
{
    printf("%s[y/n]\n", prompt);
    switch(getchar())
    {
        case 'y':
            return true;
        default:
            return false;
    }
}

void recordInfo()
{
    FILE *fp = fopen("rec.info", "a");
    int again = 1;
    struct Info information = { 0 };

    printf("职工信息录入");
    while(again)
    {
        printf("请输入职工编号：\n");
        myScanf("%d", &information.num);
        printf("请输入职工姓名：\n");
        myScanf("%s", &information.name);
        printf("请输入职工性别：\n");
        myScanf("%d", &information.sex);
        printf("请输入职工出生年月：\n");
        myScanf("%04d/%02d/%02d", &information.birthday.year, &information.birthday.month, &information.birthday.day);
        printf("请输入职工学历：\n");
        myScanf("%d", &information.education);
        printf("请输入职工职务：\n");
        myScanf("%s", &information.duty);
        printf("请输入职工工资：\n");
        myScanf("%d", &information.wage);
        printf("请输入职工地址：\n");
        myScanf("%s", &information.addr);
        printf("请输入职工电话：\n");
        myScanf("%s", &information.phone);
        fwrite(&information, sizeof(struct Info), 1, fp);
        if(confirm("是否继续录入？") != true)
        {
            again = 0;
        }

    }
    fclose(fp);
    return;
}

static void showInfo(struct Info *informat)
{
    static const char *sexStr[] = { "男", "女" };
    static const char *eduStr[] = {
        "high", "junior", "college",
        "master", "doctor"
    };

    putchar('\n');
    printf("职工编号：%d\n", informat->num);
    printf("职工姓名：%s\n", informat->name);
    printf("职工性别：%s\n", sexStr[informat->sex]);
    printf("出生年月：%04d/%02d/%02d\n",
            informat->birthday.year,
            informat->birthday.month,
            informat->birthday.day);
    printf("职工学历：%s\n", eduStr[informat->education]);
    printf("职工职务：%s\n", informat->duty);
    printf("职工工资：%d\n", informat->wage);
    printf("地址：%s\n", informat->addr);
    printf("职工电话：%s\n", informat->phone);
    return;
}

void viewInfo()
{
    FILE *fp = fopen("rec.info", "rb");
    struct Info information = { 0 };
    while(fread(&information, sizeof(struct Info), 1, fp))
    {
        showInfo(&information);
    }
    fclose(fp);
    return;
}

void queryInfo()
{
    int choose = 0;
    int count;
    Condition condition;
    FILE *fp = fopen("rec.info","r+");
    struct Info information = { 0 };

    do {
        count = 0;

        printf("请选择查询类型：\n");
        printf("1.按工资查询\n"
               "2.按学历查询\n"
               "0.退出信息查询\n");
        myScanf("%d", &choose);
        if(!choose || choose >= 3)
        {
            if(!choose)
                break;
            if(confirm("无法识别，是否重新输入") == true)
            {
                continue;
            }
            break;//跳出循环关闭文件
        }

        printf("输入工资或学历编号进行查询\n");
        myScanf("%d", &condition);
        while(fread(&information, sizeof(struct Info), 1, fp))
        {
            if(choose == 1)        //按工资查询
            {
                if(information.wage > condition.wage)
                {
                    showInfo(&information);
                    count++;
                }
            }
            else if(choose == 2)        //按学历查询
            {
                if(information.education == condition.edu)
                {
                    showInfo(&information);
                    count++;
                }
            }
        }
        printf("符合条件的共有%d个\n", count);

        if(confirm("是否继续查询") != true)
            break;
        rewind(fp);
    } while(1);

    fclose(fp);

    return;
}

void editInfo()
{
    int num,i;
    FILE *fp = fopen("rec.info", "r+");
    struct Info information = { 0 };

    do {
        i = -1;

        printf("请输入要修改的职工编号：\n");
        myScanf("%d", &num);
        while(fread(&information, sizeof(struct Info), 1, fp))
        {
            if(information.num == num)
            {
                fseek(fp, 0 - sizeof(struct Info), SEEK_CUR);
                printf("\n1.修改编号\n"
                       "2.修改姓名\n"
                       "3.修改性别\n"
                       "4.修改出生年月\n"
                       "5.修改学历\n"
                       "6.修改职务\n"
                       "7.修改工资\n"
                       "8.修改地址\n"
                       "9.修改电话\n"
                       "0.退出修改\n");
                printf("请输入操作编号：\n");
                myScanf("%d", &i);
                if(!i)//用来退出
                {
                    break;
                }
                switch(i)
                {
                    case 1:
                        printf("请输入职工编号：\n");
                        myScanf("%d", &information.num);
                        break;
                    case 2:
                        printf("请输入职工姓名：\n");
                        myScanf("%s", &information.name);
                        break;
                    case 3:
                        printf("请输入职工性别：\n");
                        myScanf("%d", &information.sex);
                        break;
                    case 4:
                        printf("请输入职工出生年月：\n");
                        myScanf("%04d/%02d/%02d", &information.birthday.year, &information.birthday.month, &information.birthday.day);
                        break;
                    case 5:
                        printf("请输入职工学历：\n");
                        myScanf("%d", &information.education);
                        break;
                    case 6:
                        printf("请输入职工职务：\n");
                        myScanf("%s", &information.duty);
                        break;
                    case 7:
                        printf("请输入职工工资：\n");
                        myScanf("%d", &information.wage);
                        break;
                    case 8:
                        printf("请输入职工地址：\n");
                        myScanf("%s", &information.addr);
                        break;
                    case 9:
                        printf("请输入职工电话：\n");
                        myScanf("%s", &information.phone);
                        break;
                    default:
                        printf("非法操作\n");
                        break;
                }
            fwrite(&information, sizeof(struct Info), 1, fp);
            }
        }
        if(i == -1)
        {
            printf("未找到该职工\n");
        }

        if(confirm("是否继续修改") != true)
            break;

        rewind(fp);    //回到文件开始处
    } while(1);

    fclose(fp);
    return;
}

void delInfo()
{
    int target;
    bool isFound = false;
    bool del;
    FILE *origFile;
    FILE *tmpFile = tmpfile();
    struct Info information = { 0 };

    do {
        del = true;
        origFile = fopen("rec.info", "r");

        printf("请输入要删除的职工的编号：\n");
        myScanf("%d", &target);
        while(fread(&information, sizeof(struct Info), 1, origFile))
        {
            if(information.num == target)
            {
                isFound = true;
                printf("确定删除“%s”？[y/n]\n", information.name);
                if(getchar() == 'n')
                {
                    getchar();
                    del = false;
                    break;
                }
                continue;
            }
            fwrite(&information, sizeof(struct Info), 1, tmpFile);
        }

        rewind(tmpFile);
        if(del)
        {
            if(isFound)
            {
                fclose(origFile);

                origFile = fopen("rec.info", "w");
                while(fread(&information, sizeof(struct Info), 1, tmpFile))
                {
                    fwrite(&information, sizeof(struct Info), 1, origFile);
                }
            }
            else
            {
                printf("没有找到编号为%d的职工\n", target);
            }
        }
        fclose(origFile);
        fclose(tmpFile);

        if(confirm("是否继续删除") == false)
            break;

    } while(1);
    return;
}
